package com.goods.business.service.imp;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.goods.business.converter.InStorkConverter;
import com.goods.business.mapper.InStockInfoMapper;
import com.goods.business.mapper.InStockMapper;
import com.goods.business.mapper.ProductMapper;
import com.goods.business.mapper.SupplierMapper;
import com.goods.business.service.InStockService;
import com.goods.common.error.BusinessCodeEnum;
import com.goods.common.error.BusinessException;
import com.goods.common.model.business.InStock;
import com.goods.common.model.business.InStockInfo;
import com.goods.common.model.business.Product;
import com.goods.common.model.business.Supplier;
import com.goods.common.response.ActiveUser;
import com.goods.common.vo.business.InStockDetailVO;
import com.goods.common.vo.business.InStockItemVO;
import com.goods.common.vo.business.InStockVO;
import com.goods.common.vo.business.SupplierVO;
import com.goods.common.vo.system.PageVO;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;

@Service
public class InStockServiceImpl implements InStockService {

  @Autowired
  private InStockMapper inStockMapper;

  @Autowired
  private InStorkConverter inStorkConverter;

  @Autowired
  private SupplierMapper supplierMapper;

  @Autowired
  private InStockInfoMapper inStockInfoMapper;

  @Autowired
  private ProductMapper productMapper;

  /**
   * 入库记录列表
   * @param pageNum
   * @param pageSize
   * @param inStockVO
   * @return
   */
  @Override
  public PageVO<InStockVO> findInStockList(Integer pageNum, Integer pageSize, InStockVO inStockVO) {
    PageHelper.startPage(pageNum,pageSize);
    Example i = new Example(InStock.class);
    Example.Criteria criteria = i.createCriteria();
    i.setOrderByClause("create_time desc");
    if (inStockVO.getInNum()!=null&&!"".equals(inStockVO.getInNum())){
      criteria.andLike("inNum","%" + inStockVO.getInNum() + "%");
    }
    if (inStockVO.getType()!=null){
      criteria.andEqualTo("type",inStockVO.getType());
    }
    if (inStockVO.getStatus()!=null){
      criteria.andEqualTo("status",inStockVO.getStatus());
    }
    if (inStockVO.getStartTime()!=null){
      criteria.andGreaterThanOrEqualTo("startTime",inStockVO.getStartTime());
    }
    if (inStockVO.getEndTime()!=null){
      criteria.andGreaterThanOrEqualTo("endTime",inStockVO.getEndTime());
    }
    List<InStock> inStocks = inStockMapper.selectByExample(i);
    List<InStockVO> inStockVOS = inStorkConverter.converterToVOList(inStocks);
    PageInfo<InStock> inStockPageInfo = new PageInfo<>(inStocks);
    return new PageVO<>(inStockPageInfo.getTotal(),inStockVOS);
  }

  /**
   * 入库单明细
   * @param id
   * @param pageNum
   * @param pageSize
   * @return
   * @throws BusinessException
   */
  @Override
  public InStockDetailVO detail(Long id, Integer pageNum, Integer pageSize) throws BusinessException {
    InStockDetailVO inStockDetailVO = new InStockDetailVO();
    InStock inStock = inStockMapper.selectByPrimaryKey(id);
    if (inStock==null){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库信息不存在");
    }
    BeanUtils.copyProperties(inStock,inStockDetailVO);
    Supplier supplier = supplierMapper.selectByPrimaryKey(inStock.getSupplierId());
    if (supplier==null){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"物资来源不存在");
    }
    SupplierVO supplierVO = new SupplierVO();
    BeanUtils.copyProperties(supplier,supplierVO);
    inStockDetailVO.setSupplierVO(supplierVO);
    String inNum = inStock.getInNum();
    //查询该单所有物资
    Example i = new Example(InStockInfo.class);
    PageHelper.startPage(pageNum,pageSize);
    i.createCriteria().andEqualTo("inNum",inNum);
    List<InStockInfo> inStockInfos = inStockInfoMapper.selectByExample(i);
    inStockDetailVO.setTotal(new PageInfo<>(inStockInfos).getTotal());
    if (!CollectionUtils.isEmpty(inStockInfos)){
      for (InStockInfo inStockInfo : inStockInfos) {
        String pNum = inStockInfo.getPNum();
        Example p = new Example(Product.class);
        p.createCriteria().andEqualTo("pNum",pNum);
        List<Product> products = productMapper.selectByExample(p);
        if (!CollectionUtils.isEmpty(products)){
          Product product = products.get(0);
          InStockItemVO inStockItemVO = new InStockItemVO();
          BeanUtils.copyProperties(product,inStockItemVO);
          inStockItemVO.setCount(inStockInfo.getProductNumber());
          inStockDetailVO.getItemVOS().add(inStockItemVO);
        }else {
          throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"编号为:["+pNum+"]的物资找不到");
        }
      }
    }else {
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库编号为:["+inNum+"]的明细找不到,或已被删除");
    }
    return inStockDetailVO;
  }

  /**
   * 添加入库单信息
   * @param inStockVO
   * @throws BusinessException
   */
  @Override
  public void addIntoStock(InStockVO inStockVO) throws BusinessException {
    String IN_STOCK_NUM = UUID.randomUUID().toString().substring(0,32).replace("-","");
    int itemNumber = 0;
    List<Object> products = inStockVO.getProducts();
    if (!CollectionUtils.isEmpty(products)){
      for (Object product : products) {
        LinkedHashMap item = (LinkedHashMap) product;
        int productNumber = (int) item.get("productNumber");
        Integer productId = (Integer) item.get("productId");
        Product dbProduct = productMapper.selectByPrimaryKey(productId);
        if (dbProduct==null){
          throw new BusinessException(BusinessCodeEnum.PRODUCT_NOT_FOUND);
        }else if (dbProduct.getStatus()==1){
          throw new BusinessException(BusinessCodeEnum.PRODUCT_IS_REMOVE,dbProduct.getName()+"物资已被回收,无法入库");
        }else if (dbProduct.getStatus()==2){
          throw new BusinessException(BusinessCodeEnum.PRODUCT_WAIT_PASS,dbProduct.getName()+"物资带着审核,无法入库");
        }else if (productNumber<=0){
          throw new BusinessException(BusinessCodeEnum.PRODUCT_IN_STOCK_NUMBER_ERROR,dbProduct.getName()+"入库数量不合法,无法入库");
        }else {
          itemNumber+=productNumber;
          InStockInfo inStockInfo = new InStockInfo();
          inStockInfo.setCreateTime(new Date());
          inStockInfo.setModifiedTime(new Date());
          inStockInfo.setProductNumber(productNumber);
          inStockInfo.setPNum(dbProduct.getPNum());
          inStockInfo.setInNum(IN_STOCK_NUM);
          inStockInfoMapper.insert(inStockInfo);
        }
      }
      InStock inStock = new InStock();
      BeanUtils.copyProperties(inStockVO,inStock);
      inStock.setCreateTime(new Date());
      inStock.setModified(new Date());
      inStock.setProductNumber(itemNumber);
      ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
      inStock.setOperator(activeUser.getUser().getUsername());
      inStock.setInNum(IN_STOCK_NUM);
      inStock.setStatus(2);
      inStockMapper.insert(inStock);
    }else {
      throw new BusinessException(BusinessCodeEnum.PRODUCT_IN_STOCK_EMPTY);
    }
  }

  /**
   * 将入库单移动至回收站
   * @param id
   * @throws BusinessException
   */
  @Override
  public void remove(Long id) throws BusinessException {
    InStock inStock = inStockMapper.selectByPrimaryKey(id);
    if (inStock==null){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库单不存在");
    }
    Integer status = inStock.getStatus();
    if (status!=0){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库单状态不正确");
    }else {
      InStock i = new InStock();
      i.setStatus(1);
      i.setId(id);
      inStockMapper.updateByPrimaryKeySelective(i);
    }
  }

  /**
   * 恢复回收站中入库单信息
   * @param id
   * @throws BusinessException
   */
  @Override
  public void back(Long id) throws BusinessException {
    InStock inStock = inStockMapper.selectByPrimaryKey(id);
    if (inStock==null){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库单不存在");
    }
    Integer status = inStock.getStatus();
    if (status!=1){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库单状态不正确");
    }else {
      InStock i = new InStock();
      i.setStatus(0);
      i.setId(id);
      inStockMapper.updateByPrimaryKeySelective(i);
    }
  }

  /**
   * 审核入库单
   * @param id
   * @throws BusinessException
   */
  @Override
  public void publish(Long id) throws BusinessException {
    InStock inStock = inStockMapper.selectByPrimaryKey(id);
    if (inStock==null){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库单不存在");
    }
    Integer status = inStock.getStatus();
    if (status!=2){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库单状态不正确");
    }else {
      InStock i = new InStock();
      i.setStatus(0);
      i.setId(id);
      inStockMapper.updateByPrimaryKeySelective(i);
    }
  }

  @Override
  public void delete(Long id) throws BusinessException {
    InStock inStock = inStockMapper.selectByPrimaryKey(id);
    if (inStock==null){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库单不存在");
    }
    Integer status = inStock.getStatus();
    if (status!=1&&status!=2){
      throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"入库单状态不正确");
    }
    inStockMapper.delete(inStock);
    String inNum = inStock.getInNum();
    Example i = new Example(InStockInfo.class);
    i.createCriteria().andEqualTo("inNum",inNum);
    inStockMapper.deleteByExample(i);
  }
}
